struct GenericVal<T>(T);
impl<T> GenericVal<T> { // for generic type impl
    fn print(&self){
        println!("GenericVal<T>");
    }
}

impl GenericVal<f32> {
    fn print_special(&self){
        println!("GenericVal<f32>");
    }
    //TODO: fn print(&self) {} //How to override the generic impl (use Traits??????)
} // speicfy for f32

struct S;
impl GenericVal<S> {//specify for type S
    fn print_special(&self){
        println!("GenericVal<S>");
    }
    //TODO: fn print(&self) {} //How to override the generic impl (use Traits??????)
} 

fn base(){
    println!("base impl for generic");
    /*
    let s = GenericVal(0_f32);
    s.print();*/

    GenericVal(0_f32).print();
    GenericVal(0_f32).print_special();

    GenericVal(S).print();
    GenericVal(S).print_special();

    GenericVal(0_i32).print();
}

struct Val {
    val: f64,
}
impl Val {
    fn value(&self) -> &f64 {
        &self.val
    }
}

struct GenVal<T> {
    gen_val: T,
}
impl<T> GenVal<T> {
    fn value(&self) -> &T {
        &self.gen_val
    }
}


pub fn main(){
    base();

    let x = Val {val: 3.0};
    println!("x .value, {}", x.value());

    let y = GenVal { gen_val: 3_i32};
    println!("y.value, {}", y.value());
}

